<template>
  <view>
    <view
      class="t-toptips"
      :style="{ top: top, background: cubgColor }"
      :class="[show ? 't-top-show' : '']"
    >
      <view v-if="loading" class="flex flex-sub">
        <view class="cu-progress flex-sub round striped active sm">
          <view :style="{ background: color, width: value + '%' }"></view>
        </view>
        <text class="margin-left">{{ value }}%</text>
      </view>
      <block v-else>{{ msg }}</block>
    </view>
    <!-- h5选取文件 -->
    <uni-popup ref="popup" type="bottom">
      <view class="h5center" v-html="html" @input="getFile($event)"></view>
    </uni-popup>
  </view>
</template>

<script>
import { mapGetters, mapActions } from 'vuex'
export default {
  computed: {
    ...mapGetters(['userInfo', 'api'])
  },
  props: {
    top: {
      type: String,
      default: 'auto'
    },
    bgColor: {
      type: String,
      default: 'rgba(49, 126, 243, 0.5)'
    },
    color: {
      type: String,
      default: '#e54d42'
    }
  },
  data() {
    return {
      html: `
			<div style="position: relative;"><button type="default" style="background-color: #007AFF;border: 0;border-radius: 5px;color:#fff;padding:5px 10px">{{$t('打开文件管理}}</button>
			<input style="position: absolute;left: 0;top: 0;opacity: 0;" type="file" id="h5File" class="input"/></div>
			`,
      cubgColor: '',
      loading: false,
      value: 5,
      show: false,
      msg: `${this.$t('执行完毕')}~`,
      h5: {
        data: {}
      }
    }
  },
  mounted() {
  },
  methods: {
    //h5选取文件
    getFile(e) {
      console.log('h5选取文件')
      document.getElementById('h5File').onchange = (res) => {
        this.$refs.popup.close()
        //h5上传
        this.updateH5(res.target.files[0], res.target.files[0].name)
      }
    },
    //h5上传
    updateH5(file, fileName) {
      console.log('h5上传')
      let mun = fileName.indexOf('.')
      let sliceName = fileName.slice(mun, fileName.length)
      let filetypes = this.h5.data.filetypes || [
        'jpg',
        'jpeg',
        'png',
        'rar',
        'txt',
        'zip',
        'doc',
        'ppt',
        'xls',
        'pdf',
        'docx',
        'xlsx',
        'mp4',
        'wmv',
        'avi',
        'mp3',
        'm4a',
        'wma',
        'JPG',
        'JPEG',
        'PNG',
        'RAR',
        'TXT',
        'ZIP',
        'DOC',
        'PPT',
        'XLS',
        'PDF',
        'DOCX',
        'XLSX',
        'MP4',
        'WMV',
        'AVI',
        'MP3',
        'M4A',
        'WMA'
      ]
      let arr = filetypes.filter((res) => {
        if (sliceName.includes(res)) {
          return res
        }
      })
      if (arr.length > 0) {
        var uploadTask = uni.uploadFile({
          url: this.h5.data.url, //仅为示例，非真实的接口地址
          file: file,
          name: 'file',
          header: {
            Authorization: this.h5.data.header.Authorization,
            us: 'app'
          },
          success: (res) => {
            if (res.statusCode === 200) {
              let data = JSON.parse(res.data)
              if (data.code === 200) {
                this.onCommit(this.$emit('up-success', { fileName, data: { id: data.data } }))
              } else {
                this.toast(data.msg)
                return this.errorHandler(data.msg, this.upErr)
              }
            } else {
              return this.errorHandler(this.$t('文件上传失败'), this.upErr)
            }
          },
          fail: () => this.errorHandler(this.$t('文件上传失败'), this.upErr)
        })
        //监听上传进度
        uploadTask.onProgressUpdate((res) => {
          this.setdefUI()
          this.value = res.progress
        })
      } else {
        this.toast(this.$t('文件格式不支持'))
      }
    },
    toast(title = '', { duration = 2000, icon = 'none' } = {}) {
      uni.showToast({ title, duration, icon })
    },
    getRequest(url) {
      let theRequest = new Object()
      let index = url.indexOf('?')
      if (index !== -1) {
        let str = url.substring(index + 1)
        let strs = str.split('&')
        for (let i = 0; i < strs.length; i++) {
          theRequest[strs[i].split('=')[0]] = unescape(strs[i].split('=')[1])
        }
      }
      return theRequest
    },

    /*
			app上传文件
			上传说明：
			currentWebview: 当前窗口webview对象
			url：上传接口地址
			name：上传文件key值
			header: 上传接口请求头
			...：body内其他参数
		*/
    appChooseFile({
      currentWebview,
      url,
      name = 'file',
      header,
      filetypes,
      crossDomain,
      ...formData
    } = {}) {
      console.log('appChooseFile')
      // #ifdef APP-PLUS
      //创建Webview窗口，用于加载新的HTML页面，可通过styles设置Webview窗口的样式，创建完成后需要调用show方法才能将Webview窗口显示出来。
      let wv = plus.webview.create(
        '/hybrid/html/pages/uploader.html',
        '/hybrid/html/pages/uploader.html',
        {
          'uni-app': 'none', //不加载uni-app渲染层框架，避免样式冲突
          top: 0,
          height: '100%',
          background: 'transparent'
        },
        {
          url,
          header,
          filetypes,
          crossDomain,
          formData,
          key: name
        }
      )
      // wv.loadURL("/hybrid/html/index.html")
      // 在Webview窗口中添加子窗口
      currentWebview.append(wv)
      // 拦截Webview窗口的URL请求
      wv.overrideUrlLoading({ mode: 'reject' }, (e) => {
        let { fileName, id, file } = this.getRequest(e.url)
        fileName = unescape(fileName) //unescape() 函数可对通过 escape() 编码的字符串进行解码。
        id = JSON.parse(unescape(id))
        return this.onCommit(this.$emit('up-success', { fileName, file, data: { id: id.data } }))
      })
      // #endif
    },
    //微信上传文件
    wxChooseFile({ url, name = 'file', header, ...formData } = {}) {
      wx.chooseMessageFile({
        count: 1,
        type: 'file',
        success: ({ tempFiles }) => {
          //console.log(tempFiles);
          let [{ path: filePath, name: fileName }] = tempFiles
          this.setdefUI()

          return uni.uploadFile({
            url,
            name,
            filePath,
            formData,
            header,
            success: (res) => {
              if (res.statusCode === 200) {
                let data = JSON.parse(res.data)
                data.data.fileName = fileName
                //可自行添加后台返回状态验证
                return this.onCommit(
                  this.$emit('up-success', { fileName, data: { id: data.data } })
                )
              }
              return this.errorHandler(this.$t('文件上传失败'), this.upErr)
            },
            fail: () => this.errorHandler(this.$t('文件上传失败'), this.upErr)
          })
        },
        fail: () => this.errorHandler(this.$t('文件选择失败'), this.upErr)
      })
    },
    //微信上选取图片或拍照
    wxChooseImage({ url, name = 'file', header, ...formData } = {}) {
      uni.chooseImage({
        count: 1, //默认9
        sourceType: ['album', 'camera'], //从相册选择
        success: ({ tempFiles }) => {
          //console.log(tempFiles);
          let [{ path: filePath, path: fileName }] = tempFiles
          this.setdefUI()
          return uni.uploadFile({
            url,
            name,
            filePath,
            formData,
            header,
            success: (res) => {
              if (res.statusCode === 200) {
                let data = JSON.parse(res.data)
                data.data.fileName = fileName
                //可自行添加后台返回状态验证
                return this.onCommit(
                  this.$emit('up-success', { fileName, data: { id: data.data } })
                )
              }
              return this.errorHandler(this.$t('文件上传失败'), this.upErr)
            },
            fail: () => this.errorHandler(this.$t('文件上传失败'), this.upErr)
          })
        },
        fail: () => this.errorHandler(this.$t('文件选择失败'), this.upErr)
      })
    },
    //h5上传
    h5FileFn(param) {
      this.h5.data = param
      this.$refs.popup.open()
    },
    /*
		上传
		*/
    upload(param = {}) {
      if (!param.url) {
        this.toast(this.$t('上传地址不正确'))
        return
      }
      if (this.loading) {
        this.toast(this.$t('还有个文件玩命处理中，请稍候') + '..')
        return
      }
      // #ifdef APP-PLUS
      return this.appChooseFile(param)
      // #endif

      // #ifdef MP-WEIXIN
      return this.wxChooseImage(param)
      // #endif

      //#ifdef H5
      return this.h5FileFn(param)
      // #endif
    },
    /*
		打开文件
		*/
    open(filePath) {
      let system = uni.getSystemInfoSync().platform
      if (system === 'ios') {
        filePath = encodeURI(filePath)
      }
      //console.log(filePath);
      uni.openDocument({
        filePath,
        success: (res) => {
          //console.log('打开文档成功');
        },
        fail(error) {
          //console.log(error);
        }
      })
    },
    /*
		下载
		 type: temporary=返回临时地址，local=长期保存到本地
		 */
    download(url, type = 'temporary') {
      if (this.loading) {
        this.toast(this.$t('还有个文件玩命处理中，请稍候') + '..')
        return
      }
      this.setdefUI()

      return new Promise((resolve, reject) => {
        let downloadTask = uni.downloadFile({
          url,
          success: ({ statusCode, tempFilePath }) => {
            if (statusCode === 200) {
              if (type === 'local') {
                uni.saveFile({
                  tempFilePath,
                  success: ({ savedFilePath }) => this.onCommit(resolve(savedFilePath)),
                  fail: () => this.errorHandler(this.$t('下载失败'), reject)
                })
              } else {
                this.onCommit(resolve(tempFilePath))
              }
            }
          },
          fail: () => this.errorHandler(this.$t('下载失败'), reject)
        })

        downloadTask.onProgressUpdate(({ progress = 0 }) => {
          if (progress <= 100) {
            this.$nextTick(() => {
              this.value = progress
            })
          }
        })
      })
    },

    onCommit(resolve) {
      this.msg = `${this.$t('执行完毕')}~`
      this.loading = false
      this.cubgColor = 'rgba(57, 181, 74, 0.5)'
      setTimeout(() => {
        this.show = false
      }, 1500)
      return resolve
    },

    setdefUI() {
      this.cubgColor = this.bgColor
      this.value = 0
      this.loading = true
      this.show = true
    },

    upErr(errText) {
      this.$emit('up-error', errText)
    },

    errorHandler(errText, reject) {
      this.msg = errText
      this.loading = false
      this.cubgColor = 'rgba(229, 77, 66, 0.5)'
      setTimeout(() => {
        this.show = false
      }, 1500)
      return reject(errText)
    }
  }
}
</script>

<style scoped lang="scss">
.t-toptips {
  width: 100%;
  padding: 18upx 30upx;
  box-sizing: border-box;
  position: fixed;
  z-index: 90;
  color: #fff;
  font-size: 30upx;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  word-break: break-all;
  opacity: 0;
  transform: translateZ(0) translateY(-100%);
  transition: all 0.3s ease-in-out;
}

.t-top-show {
  transform: translateZ(0) translateY(0);
  opacity: 1;
}
.h5center {
  display: flex;
  justify-content: center;
  padding: 10px 0;
  background-color: #ffffff;
  .button {
    background-color: #007aff;
    border: 0;
    border-radius: 5px;
  }
}
</style>
